/*
 * @author Chris
 * @since 2023/1/21 19:50
 *
 * @brief    The project will start step motor in your config circle.
 *
 * @note     ...
 *
 * @warning  Do not to ...
 *
 * Change Logs:
 *   Date           Author       Notes
 *   2023/1/21     Chris        the first version
 */

#include "reg51.h"

unsigned long beat = 0; // 节拍数

// 步进电机八节拍模式真值表
unsigned char __code stepperMotorTruthTable[8] = {
        0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
};

void StartMotor(unsigned long angle);

int main() {
    EA = 1;      // 使能总中断
    TMOD = 0x01; // 设置 T0 为模式 1
    TH0 = 0xF8;  // 为 T0 赋初值，定时 2ms
    TL0 = 0xCD;

    ET0 = 1;     // 使能 T0 中断
    TR0 = 1;     // 启动 T0

    StartMotor(360 * 20);   // 20 圈
    while (1);
}

void StartMotor(unsigned long angle) {
    EA = 0; // 关闭中断，防止计算节拍时出现误差
    beat = angle / 360 * 4076;  // 一圈实测 4076 节拍
    EA = 1;
}

/**
 * 定时器 T0中断服务函数
 */
void InterruptTimer0() __interrupt(1) {
    static unsigned char index = 0;
    TH0 = 0xF8;  // 为 T0 赋初值，定时 2ms
    TL0 = 0xCD;

    if (beat <= 0) {
        P1 = P1 | 0x0F;
        return;
    }

    P1 = P1 & 0xF0 | stepperMotorTruthTable[index++];
    index = index & 0x07;
    beat--;
}

